#include<iostream>
#include<vector>
#include<unistd.h>
#include<semaphore.h>
#include<pthread.h>

using namespace std;

#define NUM 8

template<class T>
class RingQueue
{
  public:
    RingQueue(int cap = NUM)
    :_cap(cap),_p_pos(0),_c_pos(0)
    {
      _q.resize(_cap);
      sem_init(&_blank_sem,0,_cap);
      sem_init(&_data_sem,0,0);
    }
    ~RingQueue()
    {
      sem_destroy(&_blank_sem);
      sem_destroy(&_data_sem);
    }

    void push(const T& data)
    {
      P(_blank_sem);//
      _q[_p_pos]=data;
      V(_data_sem);
      _p_pos++;
      _p_pos%= _cap;
    }

    void pop(T& data)
    {
      P(_data_sem);
      data = _q[_c_pos];
      V(_blank_sem);

      _c_pos++;
      _c_pos%=_cap;
    }

  private:
    void P(sem_t& s)
    {
      sem_wait(&s);
    }

    void V(sem_t& s)
    {
      sem_post(&s);
    }

  private:
      vector<T> _q;
      sem_t _blank_sem;//描述空间资源
      sem_t _data_sem;//描述数据资源
      int _cap;//容量
      int _p_pos;//生产位置
      int _c_pos;//消费位置
};
